/**
 * Widok dla analogowego wskaźnika
 */
package com.beans.indicator.view;

import com.beans.indicator.constans.IndicatorConstans;
import com.beans.indicator.model.IndicatorModel;
import java.awt.*;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.geom.AffineTransform;
import java.util.Observable;

/**
 *
 * @author Wojtek
 */
public class AnalogIndicatorView extends AbstractIndicatorView {

    //średnica tarczy wskaźnika
    private int size = 200;
    private int size2= 180;
    //współrzędne środka tarczy
    private int centerX = 105 , centerY = 105;
    //odstęp pomiędzy tarczą a granicą komponentu
    private int spacing = 0;
    private int spacing2 = 14;
    //punkt w którym ma zacząć malować podziałkę
    //0.25 PI czyli startujemy na godzinie 4:30 (0 na godzinie 6:00)
    private final static float offset = (float)(1/4.0 * Math.PI);
    private Color diodeOn = new Color(255,0,51);
    private Color diodeOff = new Color(153,0,51); 
    
     protected AffineTransform hourTransform =  
           AffineTransform.getRotateInstance(0, 0, 0);
      
    public AnalogIndicatorView(IndicatorModel model) {
        super(model);
        int ps = size + 2*spacing;
        setPreferredSize(new Dimension(ps, ps));
        //dodajemy listener na zmianę rozmiaru komponentu
        this.addComponentListener(new ComponentListener() {

            public void componentResized(ComponentEvent e) {
                int w = getWidth();
		int h = getHeight();
		size = ((w < h) ? w : h) - 2 * spacing;
                size2=size-size/10;
                spacing2=size/20;
		centerX = size / 2 + spacing;
		centerY = size / 2 + spacing;
            }

            public void componentMoved(ComponentEvent e) {
            }

            public void componentShown(ComponentEvent e) {
            }

            public void componentHidden(ComponentEvent e) {
            }
        });
    }


    @Override
    protected void paintIndicatorFace(Graphics g) {
        Graphics2D g2 = getAAInstance(g);
        g2.setColor(foreground);
	g2.fillOval(spacing, spacing, size, size);
	g2.setColor(background);
	g2.fillOval(spacing2, spacing2, size2, size2);
        g2.setColor(Color.BLACK);
	for (int sec = 0; sec <= tickCount; sec++) {
            int ticStart;
            if (sec % largeTickInterval == 0) {
                ticStart = size2 / 2 - size2/8;
            } else {
                ticStart = size2 / 2 - size2/15;
            }
            drawRadius(g2, centerX, centerY, offset + getRadsPerTick() * sec, ticStart, size2 / 2);
	}
        drawLabels(g2, size2/2,model.getMinValue(),model.getMaxValue());
    }
    @Override
    protected void paintDiode(Graphics g){
        Graphics2D g2 = getAAInstance(g);
        Color c = null;
        if(model.isValueCritical()) {
                c = diodeOn;
            } else {
                c = diodeOff;
            }
        g2.setColor(c);
        g2.fillOval(centerX-size2/20, centerY+size2/10, size2/10, size2/10);
    }
    
    @Override
    protected void paintTitle(Graphics g){
        Graphics2D g2 = getAAInstance(g);
        g2.setColor(Color.BLACK);
        Font f = this.getFont();
        g2.setFont(new Font(f.getFontName(), Font.PLAIN, size/10));
        FontMetrics fm = g.getFontMetrics();
        g2.drawString(title, size2/2-fm.stringWidth(title)/2+spacing2,size2/2 - size2/10+spacing2);
    }

    @Override
    protected void paintIndicator(Graphics g) {
        Graphics2D g2 = getAAInstance(g);
        g2.setColor(colorIndicator);
        drawIndicator(g2, centerX, centerY, offset+(1.5*Math.PI*(model.getMaxValue()-model.getValue()))/model.getMaxValue(), 0);
    }

    private void drawRadius(Graphics2D g, int x, int y, double angle, int minRadius, int maxRadius) {
    	float sin = (float) Math.sin(angle);
        float cos = (float) Math.cos(angle);
	int dxmin = (int) (minRadius * sin);
	int dymin = (int) (minRadius * cos);
	int dxmax = (int) (maxRadius * sin);
	int dymax = (int) (maxRadius * cos);
	g.drawLine(x + dxmin, y + dymin, x + dxmax, y + dymax);
    }
    
    private void drawLabels(Graphics2D g, int maxRadius,int min, int max){
        Font f = this.getFont();
        g.setFont(new Font(f.getFontName(), Font.PLAIN, size2/25));
        double a=(max-min)/20.0;
        double b=0;
        for (double hour = min; hour <= max; hour+=a)
      {
         double angle2 = ((int)b+(max/2))*1.5*Math.PI/max;
         int x2 = (int) (Math.cos(angle2)*(maxRadius-size2/6))+maxRadius+size2/40;
         int y2 = (int) (Math.sin(angle2)*(maxRadius-size2/6))+maxRadius+size2/15;
         g.drawString(""+hour, x2, y2);
         b+=a+min/20;
      }
    }
    
    private void drawIndicator(Graphics2D g, int x, int y, double angle, int minRadius)
    {
        float sin = (float) Math.sin(angle);
        float cos = (float) Math.cos(angle);
	int dxmin = (int) (minRadius * sin);
	int dymin = (int) (minRadius * cos);
        Point p1 = new Point((x+dxmin)-size2/30, y+dymin);
        Point p2 = new Point(x+0,y+size2/2);
        Point p3 = new Point((x+dxmin)+size2/30, y+dymin);
        Point p4 = new Point(x+dxmin,(y+dymin)+size2/20);
        int[] xs = { p1.x, p2.x, p3.x, p4.x };
	int[] ys = { p1.y, p2.y, p3.y, p4.y };
        Polygon triangle = new Polygon(xs, ys, xs.length);
        hourTransform.setToRotation(-angle, x+dxmin, y+dymin);
        g.transform(hourTransform);
        g.fillPolygon(triangle);
    }

    private float getRadsPerTick() {
        return (float) (1.5*Math.PI/tickCount);
    }

}
